import importlib
import os
from pathlib import Path
import shutil
import tempfile
import zipfile

from flask_app import EXCLUDED_FILES
from lambda_helper.http_handler import HttpRequest
from lambda_helper.s3_boto import get_boto3_client

current_dir = os.path.dirname(os.path.abspath(__file__))
lambda_dir = os.path.join(current_dir, 'lambda_functions')
lambda_path_list = set()


def copy_files_to_dir(source_dir, target_dir):
    for item in os.listdir(source_dir):
        src_path = os.path.join(source_dir, item)
        dst_path = os.path.join(target_dir, item)

        if os.path.isdir(src_path):
            # 如果是子目录，递归复制
            shutil.copytree(src_path, dst_path, dirs_exist_ok=True)  # Python 3.8+ 支持 dirs_exist_ok
        else:
            # 如果是文件，直接复制
            shutil.copy2(src_path, dst_path)

for filename in os.listdir(lambda_dir):
    if filename.endswith('.py') and not filename.startswith('.'):
        module_name = filename[:-3]  # 去掉.py后缀
        # 跳过排除的文件
        if module_name in EXCLUDED_FILES:
            continue
            
        try:
            # 动态导入模块
            spec = importlib.util.spec_from_file_location(module_name, os.path.join(lambda_dir, filename))
            module = importlib.util.module_from_spec(spec)
            spec.loader.exec_module(module)
            # 检查是否有继承HttpRequest的类
            for name, obj in module.__dict__.items():
                if isinstance(obj, type) and issubclass(obj, HttpRequest) and obj is not HttpRequest:
                    lambda_path_list.add(os.path.join(lambda_dir, filename))
                
        except Exception as e:
            print(f"加载模块 {module_name} 时出错: {e}")

lambda_path_list = list(lambda_path_list)
print('可用的lambda函数列表:')
for i, lambda_path in enumerate(lambda_path_list):
    print(f"{i+1}. {lambda_path}")
while True:
    try:
        choice = input(f"\n请选择一个需要发布的lambda函数 (1-{len(lambda_path_list)}): ")
        choice_index = int(choice) - 1
        
        if 0 <= choice_index < len(lambda_path_list):
            selected_file = lambda_path_list[choice_index]
            break
        else:
            print(f"请输入1到{len(lambda_path_list)}之间的数字")
    except ValueError:
        print("请输入有效的数字")

selected_name = Path(selected_file).name[:-3]
temp_dir = tempfile.mkdtemp()
print(f"创建临时目录: {temp_dir}")
try:
    # 复制文件到临时目录
    lambda_function_path = os.path.join(temp_dir, 'lambda_function.py')
    shutil.copy2(selected_file, lambda_function_path)
    print(f"复制文件到临时目录: {selected_file} -> {lambda_function_path}")
    # 在结尾添加lambda_handler
    py_scripts = '''
def lambda_handler(event, context):
    return ValidateHttp(event, context).build_response()
'''
    # 写入lambda_handler
    with open(lambda_function_path, 'a', encoding='utf-8') as f:
        f.write(py_scripts)
    print(f"写入lambda_handler: {lambda_function_path}")
    # 将lambda_helper下复制到临时目录中
    lambda_helper_dir = os.path.join(current_dir, 'lambda_helper')
    shutil.copytree(lambda_helper_dir, os.path.join(temp_dir, 'lambda_helper'))
    print(f"复制lambda_helper到临时目录: {lambda_helper_dir} -> {os.path.join(temp_dir, 'lambda_helper')}")
    # 复制package/common到临时目录
    package_common_dir = os.path.join(current_dir, 'packages', 'common')
    copy_files_to_dir(package_common_dir, os.path.join(temp_dir))
    print(f"复制package/common到临时目录: {package_common_dir} -> {os.path.join(temp_dir)}")
    # 复制package/lambda_name目录
    package_lambda_name_dir = os.path.join(current_dir, 'packages', selected_name)
    copy_files_to_dir(package_lambda_name_dir, os.path.join(temp_dir))
    print(f"复制package/lambda_name到临时目录: {package_lambda_name_dir} -> {os.path.join(temp_dir)}")

    # 创建zip文件
    zip_filename = f"{selected_name}.zip"
    zip_path = os.path.join(current_dir, zip_filename)
    
    with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, dirs, files in os.walk(temp_dir):
            for file in files:
                file_path = os.path.join(root, file)
                arcname = os.path.relpath(file_path, temp_dir)
                zipf.write(file_path, arcname)
                
    s3_client = get_boto3_client('s3')
    bucket_name = 'zhuchundashuaige'
    s3_key = f'lambda_publish/{zip_filename}'
    
    print(f"上传到S3: s3://{bucket_name}/{s3_key}")
    s3_client.upload_file(zip_path, bucket_name, s3_key)
    
    print(f"✅ 成功上传 {zip_filename} 到 s3://{bucket_name}/{s3_key}")
     # 清理临时文件
    os.remove(zip_path)
    print(f"清理临时zip文件: {zip_filename}")

    # 上传给对应的lambda函数
    lambda_client = get_boto3_client('lambda')
    lambda_client.update_function_code(
        FunctionName=selected_name,
        S3Bucket=bucket_name,
        S3Key=s3_key,
        Publish=True
    )
    print(f"✅ 成功上传 {zip_filename} 到 lambda函数: {selected_name}")
except Exception as e:
        print(f"❌ 错误: {str(e)}")
finally:
    # 清理临时目录
    # shutil.rmtree(temp_dir)
    print(f"清理临时目录: {temp_dir}")